package com.jiepos.mpos.pay.quickpay.service.epaypp;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.epayplusplus.api.EpayppApiException;
import com.epayplusplus.api.EpayppResponse;
import com.jiepos.mpos.common.constant.SystemConstant;
import com.jiepos.mpos.core.util.StringUtils;
import com.jiepos.mpos.pay.quickpay.service.IQuickPayService;


/**
* 标题:
* 模块: 融商支付渠道服务类(API)
* 描 述: <描述>
* 版权: Copyright (c) 2017 江苏杰博实信息技术有限公司
* @author 杨剑武
* @version 1.0
* @since 2017年12月4日
* @history（历次修订内容、修订人、修订时间等）
*/
@Service("EPAYPP_TERM")
@SuppressWarnings("rawtypes")
public class EpayppApiService extends EpayppCommonService implements IQuickPayService {
	private static final Logger _log = LoggerFactory.getLogger(EpayppApiService.class);
	private static final String EPAYPP_RSPMSG_MIN = "同一会员一分钟内只能交易一次";
	private static final String EPAYPP_RSPMSG_HOUR = "同一会员两个小时内只能交易六次";
			
	/**
	 * @param channelMchntCd
	 * @param orderNo
	 * @param orderAmt
	 * @param mobile
	 * @param certNo
	 * @param userName
	 * @param cardNo
	 * @param remark
	 * @param dataMap
	 * @return
	 */
	@Override
	public Map payOrder(String channelMchntCd, String orderNo, String orderAmt, String mobile, String certNo,
			String userName, String cardNo, String remark, Map dataMap) {
		Map<String, String> reqMap = new HashMap<String, String>();
		reqMap.put("loc_trace_no", String.valueOf(dataMap.get("loc_trace_no")));
		try {

			// 验证是否为62开头的信用卡
			if (!verificationCardNo(String.valueOf(dataMap.get("act_out_no")))) {
				reqMap.put("rspcode", SystemConstant.RSPCODE_ERROR);
				reqMap.put("rspmsg", EPAYPP_RSPMSG_62);
				return getStandardData(reqMap);
			}

			// 验证时间段交易次数
			if (!channelLimit(dataMap, reqMap)) {
				appLogTransJnlsPayService.update(reqMap, SystemConstant.RSPCODE_INVALID, reqMap.get("rspmsg"));
				return getStandardData(reqMap);
			}

			// 第一次正常调用支付
			epaypp(reqMap, dataMap, true);
			// 当响应码为1101110008(卡未开通快捷支付),重新调用支付接口
			if (SystemConstant.EPAYPP_1101110008.equals(reqMap.get("rspcode"))) {
				epaypp(reqMap, dataMap, false);
			}
			return getStandardData(reqMap);
		} catch (Exception e) {
			_log.error("融商支付[{}]会员[{}]发生异常![{}]", dataMap.get("custom_no"), dataMap.get("loc_trace_no"), e);
			return null;
		}
	}
	
	/**
	 * 
	 * 接口: 融商支付接口
	 * @param reqMap 标准化请求map
	 * @param dataMap 标准化渠道报文
	 * @param flag(true代表第一次调用,false代表第二次调用)
	 * @return
	 * @author 杨剑武
	 * @throws EpayppApiException 
	 * @since 2018年1月12日
	 */
	private void epaypp(Map<String, String> reqMap, Map dataMap, boolean flag) throws Exception {
		EpayppResponse response = null;
		// 检查商户银行卡快捷支付功能是否已开通
		boolean openFlag = false;		
		if (!flag || !(openFlag = getChannelBankcard(dataMap))) {
			response = epayppMerchantCardExpressPayOpen(dataMap);
			if (!response.isSuccess()) {
				_log.warn("[{}]会员[{}]交易流水号商户银行卡快捷支付功能开通请求失败", dataMap.get("custom_no"), dataMap.get("loc_trace_no"));
				getRespCode(reqMap, response);
				return;
			} else if (response.isSuccess() && (flag ? saveChannelBankcard(dataMap) : true)) {
				openFlag = true;
			}
		}
		
		if (openFlag) {
			if (flag) {
				response = epayppTradeCreate(dataMap);
				if (!response.isSuccess()) {
					_log.warn("[{}]会员[{}]交易流水号快捷支付交易创建失败", dataMap.get("custom_no"), dataMap.get("loc_trace_no"));
					getRespCode(reqMap, response);
					return;
				}
			}
			response = epayppWithoutCardTradePay(dataMap);
			if (!response.isSuccess()) {
				_log.warn("[{}]会员[{}]交易流水号交易支付请求失败", dataMap.get("custom_no"), dataMap.get("loc_trace_no"));
				getRespCode(reqMap, response);
			} else {
			    appLogTransJnlsPayService.updateTraceNoIsSendRand(String.valueOf(dataMap.get("loc_trace_no")));
				reqMap.put("rspcode", response.getResultCode());
				reqMap.put("rspmsg", response.getResultCodeMsg());
			}
		}
	}

	/**
	 * @param paramMap
	 * @return
	 */

	@Override
	public boolean noticeOrder(Map<String, String> paramMap) {
		_log.info("融商异步通知原始数据map=[{}]",paramMap);
		Map<String, String> standardMap = noticeStandard(paramMap);
		boolean flag = false;
		try {
			flag = noticeService.noticeUpdate(standardMap);
		} catch (Exception e) {
			flag = false;
			_log.error("融商异步通知更新发生异常", e);
		}
		return flag;
	}
	
	
	/**
	 * @param queryMap
	 * @return
	 */

	@Override
	public Map<String, String> queryChannelOrder(Map<String, String> queryMap) {
		_log.info("融商主动查询请求的map[{}]", queryMap);
		try {
			Map<String, Object> repMap = epayppTradeQuery(queryMap);
			
			return queryStandard(repMap,queryMap.get("loc_trace_no"));
		}catch (Exception e) {
			_log.error("融商主动查询请求发生异常", e);
			return new HashMap<String, String>();
		}
		
	}
	
	@Override
	public Map<String, String> verifyCode(Map<String, String> dataMap) {
		EpayppResponse response = null;
		Map<String, String> reqMap = new HashMap<String, String>();
		try {
			response = epayppWithoutCardTradeExpressVerifyCodeSubmit(dataMap);
			if (response.isSuccess()) {
				reqMap.put("rspcode", response.getResultCode());
				reqMap.put("rspmsg", response.getResultCodeMsg());
			} else {
				_log.warn("[{}]会员[{}]交易手机验证码验证请求失败", dataMap.get("custom_no"), dataMap.get("loc_trace_no"));
				getRespCode(reqMap,response);
			}
			reqMap.put("loc_trace_no", String.valueOf(dataMap.get("loc_trace_no")));
			return getStandardData(reqMap);
		} catch (Exception e) {
			_log.error("融商支付[{}]会员[{}]交易手机验证码验证发生异常![{}]", dataMap.get("custom_no"), dataMap.get("loc_trace_no"), e);
			return null;
		}
	}

	
	/**
	 * 
	 * 接口: 验证银行卡是否开通
	 * @param dataMap
	 * @return
	 * @since 2017年12月4日
	 */
	private boolean getChannelBankcard(Map dataMap) {
		try {
			Map<String,Object> data =  appPayDao.getChannelBankcard(String.valueOf(dataMap.get("bankcard_uuid")),
					String.valueOf(dataMap.get("channel_No")));
			if(!StringUtils.isEmpty(data)){
				return true;
			}
		} catch (SQLException e) {
			 _log.error("验证银行卡是否开通发生异常!",e);
		}
		 return false;
	}
	
	/**
	 * 
	 * 接口: 保存渠道银行开通记录
	 * @param dataMap
	 * @return
	 * @author 杨剑武
	 * @since 2017年12月5日
	 */
	private boolean saveChannelBankcard(Map dataMap) {
		try {
			appPayDao.saveChannelBankcard(String.valueOf(dataMap.get("bankcard_uuid")),
					String.valueOf(dataMap.get("channel_No")),null,null,String.valueOf(dataMap.get("login_id")));
			return true;
		} catch (Exception e) {
			 _log.error("保存渠道银行卡开通记录发生异常!",e);
			return false;
		}
	}

	
		
	@Override
	public Map<String, String> getStandardData(Map<String, String> reqMap) throws Exception{
		Map<String, String> respMap = new HashMap<String, String>();
		Assert.notNull(reqMap.get("loc_trace_no"));
		Map<String, String> infoMap = appLogTransJnlsPayService.getTranInfo(reqMap.get("loc_trace_no"));
		log.info("融商支付响应报文为:[{}],[{}]交易对应的查询数据为:[{}]",reqMap,reqMap.get("loc_trace_no"),infoMap);
		Map<String, Object> traceTime = mainBusinessService.getSystemTime();
		respMap.put("loc_dt", String.valueOf(traceTime.get("loc_dt")));//交易日期
		respMap.put("loc_ts", String.valueOf(traceTime.get("loc_ts")));//交易日期
		respMap.put("trf_mchnt_cd", infoMap.get("trf_mchnt_cd"));// 商户编号（渠道）
		respMap.put("trf_term_id", infoMap.get("trf_term_id"));// 终端编号（渠道）
		respMap.put("complete_dt", reqMap.get("complete_dt"));// 订单完成日期（渠道）
		respMap.put("complete_ts", reqMap.get("complete_ts"));// 订单完成时间
		respMap.put("custom_no", infoMap.get("custom_no"));// 客户编号（支付系统）
		respMap.put("term_id", reqMap.get("term_id"));// 本地流水号（支付系统)
		respMap.put("trf_trace_no", reqMap.get("trf_trace_no"));// 渠道方流水号（渠道）
		respMap.put("loc_trace_no", reqMap.get("loc_trace_no"));
		respMap.put("trs_stat", reqMap.get("trs_stat"));// 交易状态
		respMap.put("stlst", infoMap.get("stlst"));// 清算状态
		respMap.put("midfee", infoMap.get("midfee"));// 商户手续费
		respMap.put("stl_amt", reqMap.get("stl_amt"));// 结算金额
		respMap.put("rspcode", reqMap.get("rspcode"));// 返回码
		respMap.put("rspmsg", reqMap.get("rspmsg"));// 交易返回信息
		respMap.put("action", reqMap.get("action"));// 银联跳转页面
		respMap.put("data", reqMap.get("data"));// 支付数据
		respMap.put("url", reqMap.get("url"));// 未使用
		respMap.put("sourceData", reqMap.get("sourceData"));// 交易返回信息
		respMap.put("channel_type", SystemConstant.CHANNEL_TYPE_API);
		respMap.put("verify_code_type", SystemConstant.VERIFY_CODE_TYPE_0);
		log.info("融商支付响应响应报文转标准化系统处理报文[{}]",respMap);
		return respMap;
	}
	
	/**
	 * 
	 * 接口: 查询时间段里同一会员短信结束次数
	 * @param dataMap
	 * @param reqMap
	 * @return
	 * @throws Exception
	 * @since 2018年1月10日
	 */
	private boolean channelLimit(Map dataMap,Map<String, String> reqMap) throws Exception {
		Map<String, Object> channelLimitMinData = appPayDao.numberOfSMS(String.valueOf(dataMap.get("trf_mchnt_cd")),String.valueOf(dataMap.get("custom_no")),1);
		if(StringUtils.isEmpty(channelLimitMinData)){
			reqMap.put("rspcode", SystemConstant.RSPCODE_ERROR);
			return false;
		}else{
			log.info("融商支付一分钟内交易次数统计:[{}]",channelLimitMinData);
			if(Integer.valueOf(String.valueOf(channelLimitMinData.get("sumCount"))) > 0){
				reqMap.put("rspcode", SystemConstant.RSPCODE_INVALID);
				reqMap.put("rspmsg", EPAYPP_RSPMSG_MIN);
				return false;
			}
		}
		Map<String, Object> channelLimitHourData = appPayDao.numberOfSMS(String.valueOf(dataMap.get("trf_mchnt_cd")),String.valueOf(dataMap.get("custom_no")),120);
		if(StringUtils.isEmpty(channelLimitHourData)){
			reqMap.put("rspcode", SystemConstant.RSPCODE_ERROR);
			return false;
		}else{
			log.info("融商支付两个小时内交易次数统计:[{}]",channelLimitHourData);
			if(Integer.valueOf(String.valueOf(channelLimitHourData.get("sumCount"))) > 5){
				reqMap.put("rspcode", SystemConstant.RSPCODE_INVALID);
				reqMap.put("rspmsg", EPAYPP_RSPMSG_HOUR);
				return false;
			}else{
				return true;
			}
		}
	}
	
	@Override
	public Map<String, String> queryChannelStlResult(Map<String, String> queryMap) {
		return null;
	}

	@Override
	public Map<String, String> sendVerifyCode(Map<String, String> reqMap) {
		return null;
	}
}
